package com.ksyun.campus.metaserver.services;

import com.ksyun.campus.common.constant.ZkConstant;
import com.ksyun.campus.common.domain.DataServer;
import com.ksyun.campus.common.util.ByteConvertUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 数据服务发现
 *
 * @author zhaozhikai
 * @date 2023/8/7 0:17
 */
@Service
@Slf4j
public class DataDiscovery {
    @Autowired
    private CuratorFramework curatorFramework;

    public static ConcurrentHashMap<String, DataServer> dataServerStore = new ConcurrentHashMap<>();

    /**
     * 开启开启监听服务, 监听 data server 信息
     */
    @PostConstruct
    private void watchDataServer() throws Exception {
        //给指定节点的子节点注册监听
        PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorFramework, ZkConstant.DATA_SERVER, true);
        pathChildrenCache.getListenable().addListener((curatorFramework, event) -> {
            PathChildrenCacheEvent.Type type = event.getType();
            String path = event.getData().getPath();
            if (type == PathChildrenCacheEvent.Type.CHILD_ADDED) {
                log.info("数据服务{}被添加~", path);
                byte[] data = event.getData().getData();
                DataServer dataServer = (DataServer) ByteConvertUtil.toObj(data, DataServer.class);
                dataServerStore.put(path,dataServer);
            }
            if (type == PathChildrenCacheEvent.Type.CHILD_REMOVED) {
                log.info("数据服务{}被移除~", path);
                dataServerStore.remove(path);
            }
            if (type == PathChildrenCacheEvent.Type.CHILD_UPDATED) {
//                log.info("数据服务{}更新~", path);
                byte[] data = event.getData().getData();
                DataServer dataServer = (DataServer) ByteConvertUtil.toObj(data, DataServer.class);
                dataServerStore.put(path,dataServer);
            }
        });
        pathChildrenCache.start();
    }

    /**
     * 获取所有的数据服务节点
     * @return
     */
    public List<String> getDataNodeList(){
        try {
            if (this.curatorFramework.checkExists().forPath(ZkConstant.DATA_SERVER) != null) {
                return this.curatorFramework.getChildren().forPath(ZkConstant.DATA_SERVER);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
